from fastapi import APIRouter, HTTPException, Query, Request
import requests
from pydantic import BaseModel
from typing import Optional
import urllib.parse
from datetime import datetime, timedelta
import json

from starlette.responses import JSONResponse, RedirectResponse, Response

# 导入用户模型
from models.models import User
from rag.user_question import query_chroma, answer_user_question

from tools.bdapi import idcard
# 导入JWT工具
from tools.myjwt import create_access_token, create_refresh_token, decode_token
from tools.myredis import r
from tools.tplant import p
from tools.comm import get_ali_object
from models.models import UserOrder
# 导入身份证OCR相关模型


user_router = APIRouter()

# 导入钉钉配置
from config.dingtalk_config import DINGTALK_CONFIG

# 钉钉应用配置
DINGTALK_CLIENT_ID = DINGTALK_CONFIG['CLIENT_ID']
DINGTALK_CLIENT_SECRET = DINGTALK_CONFIG['CLIENT_SECRET']
DINGTALK_REDIRECT_URI = DINGTALK_CONFIG['REDIRECT_URI']


class DingTalkUserInfo(BaseModel):
    unionid: str
    openid: str
    nickname: str
    avatar_url: str


class DingTalkLoginResponse(BaseModel):
    access_token: str
    refresh_token: str
    expires_in: int
    scope: str
    user_info: Optional[DingTalkUserInfo] = None


@user_router.get("/dingtalk/auth")
async def dingtalk_auth(request: Request):
    """
    钉钉登录授权 - 重定向到钉钉授权页面
    """
    types = request.query_params.get('types') or 'dingding'
    class_name = p.get_sl_class(types)
    auth_url = class_name.geturl()
    return RedirectResponse(url=auth_url)


@user_router.get("/dingtalk/callback")
async def dingtalk_callback(request: Request):
    """
    钉钉登录回调接口
    """
    types = request.query_params.get('types') or 'dingding'
    authCode = request.query_params.get('code')
    class_name = p.get_sl_class(types)
    userinfo = class_name.callback(authCode)

    try:
        # 解析钉钉用户信息
        phone = userinfo.get('phone')
        name = userinfo.get('name')
        avatar = userinfo.get('avatar')
        # uid = userinfo.get('uid')
        
        # 验证必要字段
        user = await User.filter(phone=phone).first()
        if not user:
            # 用户不存在，创建新用户（只包含三个字段：手机号、昵称、头像）
            user = await User.create(
                phone=phone,
                nickname=name,
                avatar=avatar
            )
            print(f"创建新用户: {user.id}, phone: {phone}, nickname: {name}")
        else:
            # 用户存在，更新用户信息（只更新昵称和头像，不更新手机号）
            user.nickname = name
            user.avatar = avatar
            await user.save()
            print(f"更新现有用户: {user.id}, nickname: {name}, avatar: {avatar}")

        # 生成JWT访问令牌和刷新令牌
        access_token_expires = timedelta(minutes=30)
        refresh_token_expires = timedelta(days=7)

        access_token = create_access_token(
            data={"sub": user.id, "phone": phone, "name": name},
            expires_delta=access_token_expires
        )
        refresh_token = create_refresh_token(
            data={"sub": user.id, "phone": phone, "name": name},
            expires_delta=refresh_token_expires
        )

        # 构建前端回调URL，将用户信息和token作为查询参数传递
        frontend_callback_url = "http://localhost:5173/dingtalk/callback"

        # 准备查询参数
        params = {
            "success": "true",
            "token": access_token,
            "refresh_token": refresh_token,
            "expires_in": "1800",  # 30分钟
            "user_info": urllib.parse.quote(json.dumps({
                "user_id": user.id,  # 数据库中的用户ID
                "name": name,
                "phone": phone,
                "nickname": name,
                "avatar": avatar
            }))
        }

        # 构建完整的回调URL
        callback_url = f"{frontend_callback_url}?{urllib.parse.urlencode(params)}"

        # 重定向到前端回调页面
        return RedirectResponse(url=callback_url)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"处理钉钉回调时发生错误: {str(e)}")



@user_router.get("/idcard")
async def user_idcard(request: Request):
    """
    获取用户身份证信息，将身份证URL存入Redis队列
    """
    url_img = request.query_params.get('url')
    user_id = request.query_params.get('user_id')
    data = {
        "url": url_img,
        "user_id": user_id
    }
    # 将URL存入Redis队列
    r.rpush("idcard_list", json.dumps(data))
    await User.filter(id=user_id).update(verify_status=1)
    print(f"身份证图片URL已存入Redis队列: {data}")
    return JSONResponse({
        'code': 200, 
        'message': '身份证图片已提交，正在识别中，请稍后.....',
        'data': "请稍后"
    })

from qiniu import Auth
@user_router.get("/qiniu/")
async def get_upload_token():
    try:
        #需要填写你的 Access Key 和 Secret Key
        access_key = 'C-87lR8O_tCm1qEf-wIbnTnB4LpJSgsJCNVKMuON'
        secret_key = 't79Knkexa3_e3LPXnc9sY9yd3EkG9KbiJfMFtHof'
        #构建鉴权对象
        q = Auth(access_key, secret_key)
        #要上传的空间
        bucket_name = 'wlgy'

        #3600为token过期时间，秒为单位。3600等于一小时
        # 添加policy参数，允许指定key
        policy = {
            'scope': bucket_name,
            'deadline': 3600
        }
        token = q.upload_token(bucket_name, None, 3600, policy)
        
        print(f"生成的七牛云token: {token[:50]}...")
        return JSONResponse({"code":10000,'data':token})
    except Exception as e:
        print(f"生成七牛云token失败: {e}")
        return JSONResponse({"code":500,'message':f'生成token失败: {str(e)}'})


#识别认证状态
@user_router.get("/idcard/status")
async def get_idcard_status(request: Request):
    """
    获取身份证识别状态
    和账号信息
    """
    authorization = request.headers.get("Authorization")
    if not authorization:
        return JSONResponse({"code": 401, "message": "缺少Authorization头"})
    
    # 提取token
    if authorization.startswith("Bearer "):
        token = authorization.replace("Bearer ", "")
    else:
        token = authorization
    
    # 验证并解析JWT
    try:
        payload = decode_token(token)
        user_id = payload.get("sub")
        
        if not user_id:
            return JSONResponse({"code": 401, "message": "Token中缺少用户ID"})

        user = await User.filter(id=user_id).first()
        if not user:
            return JSONResponse({"code": 404, "message": "用户不存在"})
        
        data = {
            "nickname": user.nickname,
            "verify_status": user.verify_status,
            "avatar": user.avatar,
            "phone": user.phone
        }
        return JSONResponse({"code": 200, "data": data})
    except Exception as e:
        print(f"获取身份证识别状态失败: {e}")
        return JSONResponse({"code": 500, "message": f"获取身份证识别状态失败: {str(e)}"})





# 1960-列车站到站时刻表 - 代码参考（根据实际业务情况修改）
@user_router.get("/train")
async def train_schedule(request: Request):
    # 基本参数配置
    apiUrl = 'https://apis.juhe.cn/fapigw/train/query'  # 接口请求URL
    apiKey = '63a7b4624861c34ab99b829e272d225e'  # 在个人中心->我的数据,接口名称上方查看
    search_type = request.query_params.get('search_type')
    departure_station  = request.query_params.get('departure_station')
    arrival_station = request.query_params.get('arrival_station')
    date = request.query_params.get('date')
    filter = request.query_params.get('filter')
    enable_booking = request.query_params.get('enable_booking','')
    departure_time_range = request.query_params.get('departure_time_range','')


    # 接口请求入参配置
    requestParams = {
        'key': apiKey,  # 接口认证密钥，用于验证身份
        'search_type': search_type,  # 搜索类型，这里设置为'北京'
        'departure_station': departure_station,  # 出发车站，设置为'北京'
        'arrival_station': arrival_station,  # 到达车站，设置为'郑州'
        'date': date,  # 查询日期，指定为'2025-11-06'
        'filter': filter,  # 过滤条件，当前为空字符串表示不过滤
        'enable_booking': enable_booking,  # 是否启用预订功能，空值表示使用默认设置
        'departure_time_range':departure_time_range ,  # 出发时间范围，设置为'上午'
    }

    # 发起接口网络请求
    response = requests.get(apiUrl, params=requestParams)

    # 解析响应结果
    if response.status_code == 200:
        responseResult = response.json()
        # 网络请求成功。可依据业务逻辑和接口文档说明自行处理。
        print("API响应结果:", responseResult)
        print("响应类型:", type(responseResult))
        print("准备返回的数据:", responseResult)
        
        # 直接返回字典，FastAPI会自动转换为JSON响应
        return responseResult
    else:
        # 网络异常等因素，解析结果异常。可依据业务逻辑自行处理。
        error_message = f'请求异常: {response.status_code}, {response.text}'
        print(error_message)
        raise HTTPException(status_code=response.status_code, detail='列车信息查询失败')



























































































@user_router.get("/rag/")
async def rag_test(request: Request):
    question = request.query_params.get('question')
    if not question:
        return JSONResponse({"code": 400, "message": "缺少question参数"})
    try:
        results = query_chroma(question)
        print(f"查询结果: {results}")
        # 获取回答并确保返回
        answer = answer_user_question(results, question)
        print(f"生成的回答: {answer}")
        return JSONResponse({"code": 200, "data": answer or "未能生成回答"})
    except Exception as e:
        import traceback
        error_details = traceback.format_exc()
        print(f"RAG处理错误: {e}\n{error_details}")
        return JSONResponse({"code": 500, "message": f"处理问题时出错: {str(e)}"})










